/* ------------------------ System includes ------------------------------- */
#include "main.h"
/* ------------------------ FreeRTOS includes ----------------------------- */
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
/* ------------------------ FreeModbus includes --------------------------- */
#include "MBapp.h"
#include "string.h"
/* ------------------------ Project includes ------------------------------ */

/* ------------------------ Defines --------------------------------------- */
uint16_t mbConnect = 0,mbSofeStus = 0;
uint8_t card_TcpPara[CARD_PARA_LEN];

/* ----------------------- Static variables ---------------------------------*/
uint16_t   usRegInputStart = REG_INPUT_START;
WORT_ST   usRegInputBuf4[REG_INPUT_NREGS];
uint16_t   usRegHoldingStart = REG_HOLDING_START;
WORT_ST   usRegHoldingBuf3[REG_HOLDING_NREGS];
uint16_t   usRegDiscreteStart = REG_DISCRETE_START;
uint8_t   usRegDiscreteBuf2[REG_DISCRETE_NREGS];
uint16_t   usRegCoilsStart = REG_COILS_START;
uint8_t   usRegCoilsBuf1[REG_COILS_NREGS];

//卡参数是否变化标志
#define UPDATA_FLAG_REM  ((SYS_MAX_CARD % 8) ? 1 : 0)
#define UPDATA_FLAG_LEN  (SYS_MAX_CARD / 8 + UPDATA_FLAG_REM)


/* ------------------------ Static functions ------------------------------ */

static void MB_ParaInit(void)
{
	
//	memset(usRegCoilsBuf1,0,sizeof(usRegCoilsBuf1));
//	memset(usRegDiscreteBuf2,0,sizeof(usRegDiscreteBuf2));
//	memset(usRegHoldingBuf3,0,sizeof(usRegHoldingBuf3));
//	memset(&usRegInputBuf4[MB_FUNEN_STUS],0,(sizeof(usRegInputBuf4)-MB_FUNEN_STUS));
	usRegInputBuf4[MB_SOFT_VERSION].word = CAR_VERSION;//

	usRegInputBuf4[MB_FUNEN_STUS].word = 0 ;
	#if (USE_IAP_TFTP == FUN_ENABLE)
	usRegInputBuf4[MB_FUNEN_STUS].word += 0x0001;
	#endif

	#if (USE_TCP_SEND == FUN_ENABLE)
	usRegInputBuf4[MB_FUNEN_STUS].word += 0x0002;
	#endif

	#if (USE_DOG_ENABLE == FUN_ENABLE)
	usRegInputBuf4[MB_FUNEN_STUS].word += 0x0004;
	#endif


	usRegInputBuf4[MB_SOFT_STUS].word = mbSofeStus;//
	usRegInputBuf4[MB_CAR_TYPE].word = CAR_USE_TYPE;//
}





//系统参数
uint8_t Read_Card_TcpPara(uint16_t addr, uint16_t len, uint8_t *buf)
{
	if(addr + len > SYSPARA_MAX_LEN)
	{
		return APP_ERR_PARM;
	}
	memcpy(buf, &card_TcpPara[addr], len);
	return APP_OK;
}

uint8_t Write_Card_TcpPara(uint16_t addr, uint16_t len, uint8_t *buf)
{
	if(addr + len > SYSPARA_MAX_LEN)
	{
		return APP_ERR_PARM;
	}
	memcpy(&card_TcpPara[addr], buf,len);
	return APP_OK;
}


void SETRegHolding3(uint8_t addr,uint16_t *data ,uint8_t len)
{
   	while(len--)
	{
		usRegHoldingBuf3[addr++].word = *data++;
	}
}
void SETOneRegHolding3(uint8_t addr,uint16_t data)
{
			usRegHoldingBuf3[addr].word  = data;
}
void GETRegHolding3(uint8_t addr,uint16_t *data ,uint8_t len)
{
   while(len--)
	 {
		 *data++	= usRegHoldingBuf3[addr++].word;
	 }

}
void SETRegInput4(uint8_t addr,uint16_t *data ,uint8_t len)
{
   while(len--)
	 {
			usRegInputBuf4[addr++].word = *data++;
	 }
}
void SETOneRegInput4(uint8_t addr,uint16_t data)
{
			usRegInputBuf4[addr].word = data;
}
void GETRegInput4(uint8_t addr,uint16_t *data ,uint8_t len)
{
   while(len--)
	 {
		 *data++	= usRegInputBuf4[addr++].word;
	 }
}
uint16_t GETOneRegInput4(uint8_t addr)
{
   return usRegInputBuf4[addr].word;
}
void SETRegDiscrete2(uint8_t addr,uint8_t *data ,uint8_t len)
{
   while(len--)
	 {
			usRegDiscreteBuf2[addr++] = *data++;
	 }
}
void GETRegDiscrete2(uint8_t addr,uint8_t *data ,uint8_t len)
{
   while(len--)
	 {
		 *data++	= usRegDiscreteBuf2[addr++];
	 }
}
void SETRegCoils1(uint8_t addr,uint8_t *data ,uint8_t len)
{
   while(len--)
	 {
			usRegCoilsBuf1[addr++] = *data++;
	 }
}
void GETRegCoils1(uint8_t addr,uint8_t *data ,uint8_t len)
{
   while(len--)
	 {
		 *data++	= usRegCoilsBuf1[addr++];
	 }
}
/* ------------------------ Implementation -------------------------------- */
osThreadId MBTaskHandle;
extern uint8_t LWIP_ETH_Updata(void);
void MB_config(void)
{
//   MB_ParaInit();
//	 while(!LWIP_ETH_Updata()){//testLW
//		 osDelay(1000);
//	 }
//	extern void MB_Server_Init(void);
//	 MB_Server_Init();
	osThreadDef(MBTask, vMBServerTask, osPriorityHigh, 0, 256);
	MBTaskHandle = osThreadCreate(osThread(MBTask), NULL);
}

void
vMBServerTask( void const *argument )
{

	 MB_ParaInit();

	 extern void MB_Server_Init(void);

   while(1){
		 if(LWIP_ETH_Updata()){
			 	 MB_Server_Init();
				 if( MBTaskHandle != NULL )
				 {
					 vTaskDelete( MBTaskHandle );
				 }
		 }
		 osDelay(50);
   }
}

/*************************************
IO input
**************************************/
#define  IO_H_START  0
#define  IO_H_MAX    7    //加强限位开关滤波
#define  IO_L_START  10
#define  IO_L_MAX    17
#define  IO_IN_CNT    16
static void CoilsReadDeal(uint8_t index){

	uint8_t status;
	static uint8_t statusCnt[IO_IN_CNT] = {0};

	switch(index){
		case 0X00:
	//		status = (KEY0_GPIO_Port->IDR & KEY0_Pin) ? 1: 0 ;
		  break;
		case 0X01:
	//		status = (KEY1_GPIO_Port->IDR & KEY1_Pin) ? 1: 0 ;
		  break;
		default:
			return;
	}
	if(status){
		if(statusCnt[index]<IO_H_MAX){
			statusCnt[index]++;
		}
		else if(statusCnt[index]>IO_L_START){
			statusCnt[index] = IO_H_START;
		}
		else
			{
			SETRegDiscrete2(index,&status ,1);
		}
	}
	else{
		if(statusCnt[index]<IO_L_START){
			statusCnt[index] = IO_L_START;
		}
		else if(statusCnt[index]<IO_L_MAX){
			statusCnt[index]++;
		}
		else
			{
			SETRegDiscrete2(index,&status ,1);
		}
	}
}
void CoilsReadAll(void)
{
	for(uint8_t i = 0;i<IO_IN_CNT;i++)CoilsReadDeal(i);
}
